bitkeeper revision 1.1159.79.15 (4151a1aaxwsNrL2Uz8ag9J-2-2nVwQ)
authorcl349@freefall.cl.cam.ac.uk <cl349@freefall.cl.cam.ac.uk>
Wed, 22 Sep 2004 16:00:42 +0000 (16:00 +0000)
committercl349@freefall.cl.cam.ac.uk <cl349@freefall.cl.cam.ac.uk>
Wed, 22 Sep 2004 16:00:42 +0000 (16:00 +0000)
Don't use fake clockframe for interrupt delivery.  Fixes all cpu time getting
accounted to the kernel and not to userspace programs.

netbsd-2.0-xen-sparse/sys/arch/xen/i386/hypervisor_machdep.c
netbsd-2.0-xen-sparse/sys/arch/xen/i386/vector.S
netbsd-2.0-xen-sparse/sys/arch/xen/include/evtchn.h
netbsd-2.0-xen-sparse/sys/arch/xen/include/hypervisor.h
netbsd-2.0-xen-sparse/sys/arch/xen/xen/clock.c
netbsd-2.0-xen-sparse/sys/arch/xen/xen/evtchn.c

index e08b5a64bd936c70dc68cea2ca6b26b6476567ce..82e998d3b6b87a7b18ae47ad3765c532c77bbc84 100644 (file)
@@ -151,7 +151,7 @@ stipending()
        return (ret);
 }
 
-void do_hypervisor_callback(struct trapframe *regs)
+void do_hypervisor_callback(struct intrframe *regs)
 {
        uint32_t l1;
        unsigned long l2;
index 165b5f06be34898cf6bdc6a6fc316a8489af76fd..db7a57485d9472955cfb983f1b58cff7da77a102 100644 (file)
@@ -1347,9 +1347,10 @@ ENTRY(hypervisor_callback)
         jb   11f
         cmpl $ecrit,%eax
         jb   critical_region_fixup
-11:     push %esp
+11:     pushl CPUVAR(ILEVEL)
+        push %esp
         call do_hypervisor_callback
-        add  $4,%esp
+        add  $8,%esp
         movl HYPERVISOR_shared_info,%esi
         xorl %eax,%eax
         movb TF_CS(%esp),%cl
index 5dd98ef25053d4eb1cf821b5befe4a60563b57b8..f12ad2801668da64b03987bba12083a5f71d1331 100644 (file)
@@ -43,7 +43,7 @@ typedef int (*ev_handler_t)(void *);
 
 void events_default_setup(void);
 void init_events(void);
-unsigned int do_event(int, struct trapframe *);
+unsigned int do_event(int, struct intrframe *);
 int event_set_handler(int, ev_handler_t, void *, int);
 
 int bind_virq_to_irq(int);
index 13442d22ebdc1a61b48243abbe7b1975372439a0..83a170485e12e103bfe9471e31c0de4b5c6f0c75 100644 (file)
@@ -83,7 +83,7 @@ extern union start_info_union start_info_union;
 
 
 /* hypervisor.c */
-void do_hypervisor_callback(struct trapframe *regs);
+void do_hypervisor_callback(struct intrframe *regs);
 void hypervisor_notify_via_evtchn(unsigned int);
 void hypervisor_enable_irq(unsigned int);
 void hypervisor_disable_irq(unsigned int);
index 16add4e591833558a20b81e88d06f3b7218752bd..2db3332d21b4c95d258abd3504baa5438b150a53 100644 (file)
@@ -51,7 +51,7 @@ __KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.1.2.2 2004/07/17 16:43:56 he Exp $");
 
 #include "config_time.h"               /* for CONFIG_TIME */
 
-static int xen_timer_handler(void *, struct trapframe *);
+static int xen_timer_handler(void *, struct intrframe *);
 
 /* These are peridically updated in shared_info, and then copied here. */
 static uint64_t shadow_tsc_stamp;
@@ -213,7 +213,7 @@ xen_initclocks()
 }
 
 static int
-xen_timer_handler(void *arg, struct trapframe *regs)
+xen_timer_handler(void *arg, struct intrframe *regs)
 {
        int64_t delta;
 
@@ -245,7 +245,7 @@ xen_timer_handler(void *arg, struct trapframe *regs)
        delta = (int64_t)(shadow_system_time + get_tsc_offset_ns() -
                          processed_system_time);
        while (delta >= NS_PER_TICK) {
-               hardclock((struct clockframe *)regs);
+               hardclock(regs);
                delta -= NS_PER_TICK;
                processed_system_time += NS_PER_TICK;
        }
index ca3f7c99f6f05af764f9fcd25b5a8ba5fb2f1344..0f275484ddcbf77713f75c8ad84f5bba02842e15 100644 (file)
@@ -123,9 +123,13 @@ init_events()
 }
 
 unsigned int
-do_event(int irq, struct trapframe *regs)
+do_event(int irq, struct intrframe *regs)
 {
        struct cpu_info *ci;
+       int ilevel;
+       struct intrhand *ih;
+       int     (*ih_fun)(void *, void *);
+       extern struct uvmexp uvmexp;
 
        if (irq >= NR_IRQS) {
 #ifdef DIAGNOSTIC
@@ -144,15 +148,46 @@ do_event(int irq, struct trapframe *regs)
 
        hypervisor_acknowledge_irq(irq);
        if (ci->ci_isources[irq] == NULL) {
+               hypervisor_enable_irq(irq);
+               return 0;
+       }
+       ilevel = ci->ci_ilevel;
+       if (ci->ci_isources[irq]->is_maxlevel <= ilevel) {
+               ci->ci_ipending |= 1 << irq;
+               /* leave masked */
                return 0;
        }
-       __asm__ __volatile__ (
-               "   movl $1f,%%esi      ;"
-               "   jmp  *%%eax         ;"
-               "1:                     "
-               : : "a" (ci->ci_isources[irq]->is_recurse),
-               "b" (ci->ci_ilevel)
-               : "esi", "ecx", "edx", "memory");
+       uvmexp.intrs++;
+       ci->ci_isources[irq]->is_evcnt.ev_count++;
+       ci->ci_ilevel = ci->ci_isources[irq]->is_maxlevel;
+       /* sti */
+       ci->ci_idepth++;
+#ifdef MULTIPROCESSOR
+       x86_intlock(regs);
+#endif
+       ih = ci->ci_isources[irq]->is_handlers;
+       while (ih != NULL) {
+               if (ih->ih_level <= ilevel) {
+#ifdef MULTIPROCESSOR
+                       x86_intunlock(regs);
+#endif
+                       ci->ci_ipending |= 1 << irq;
+                       /* leave masked */
+                       ci->ci_idepth--;
+                       splx(ilevel);
+                       return 0;
+               }
+               ci->ci_ilevel = ih->ih_level;
+               ih_fun = (void *)ih->ih_fun;
+               ih_fun(ih->ih_arg, regs);
+               ih = ih->ih_next;
+       }
+#ifdef MULTIPROCESSOR
+       x86_intunlock(regs);
+#endif
+       hypervisor_enable_irq(irq);
+       ci->ci_idepth--;
+       splx(ilevel);
 
        if (0 && irq == 4)
                printf("do_event %d done, ipending %08x\n", irq,